#include <string.h>
#include <iostream>
using std::cout;
using std::endl;
using std::ostream;

class Base
{
public:
    Base(const char * data)
    : _data(new char[strlen(data) + 1]())
    {   
        cout << "Base( const char* )" << endl;   
        strcpy(_data, data);
    }

    Base(const Base & rhs)
    : _data(new char[strlen(rhs._data) + 1]())
    {   
        cout << "Base(const Base&)" << endl;
        strcpy(_data, rhs._data);
    }

    Base & operator=(const Base & rhs)
    {
        cout << "Base & operator=(const Base&)" << endl;
        if(this != &rhs) {
            delete [] _data;
            _data = new char[strlen(rhs._data) + 1]();
            strcpy(_data, rhs._data);
        }
        return *this;
    }

    friend ostream & operator<<(ostream &os, const Base & rhs);

private:
    char * _data;
};
    
ostream & operator<<(ostream &os, const Base & rhs)
{
    os << rhs._data;
    return os;
}

class Derived
: public Base
{
public:
    Derived(const char * data, long derived)
    : Base(data)
    , _derived(derived)
    {   cout << "Derived(const char *)" << endl;   }

    //1. 当派生类没有显式定义复制控制函数，执行派生类间对象的复制控制操作时，
    //对于基类部分的复制控制函数会自动调用

    friend ostream &operator<<(ostream &os, const Derived & rhs);
private:
    long _derived;
};

ostream &operator<<(ostream &os, const Derived & rhs)
{
    os << (Base&)rhs << ", derived:" << rhs._derived;
    return os;
}

void test0()
{
    Derived d1("hello", 10);
    //派生类对象可以转换为基类对象
    cout << "d1:" << d1 << endl;
    Derived d2 = d1;
    cout << "d2:" << d2 << endl << endl;

    Derived d3("world", 100);
    cout << "d3:" << d3 << endl;
    d3 = d1;
    cout << "d3:" << d3 << endl;

}

int main()
{
    test0();
    return 0;
}

